 <!--
 * @Description: 角色菜单权限
 * @version: 电子名片2.0
 * @Author: 付小清
 * @Date: 2020-10-30 14:28:39
 * @LastEditors: 付小清
 * @LastEditTime: 2020-12-21 16:42:23
-->

<template>
  <div class="mainbox">
    <el-container>
      <!-- 搜索 -->
      <el-header height="auto">
        <search
          :search="searchs"
          @get-list="onSubmit"
          @init-params="onReset()"
        />
      </el-header>
      <!-- 表格 -->
      <el-container>
        <el-main>
          <adminTable
            ref="refTable"
            :search-show="false"
            :search-btn="false"
            :selection-list="selectionList"
            :api-fun="apiFun"
            :table-data.sync="tableData"
          >
            <template slot="search" />
            <!-- 表格操作 -->
            <template slot="column">
              <!-- <el-table-column type="selection" width="55" align="center" /> -->
              <el-table-column label="单选" width="55" align="center">
                <template slot-scope="scope">
                  <el-radio
                    v-model="selectionId"
                    :label="scope.row.roleId"
                    @click.native="getThisRow(scope.row.roleId)"
                    @change.native="currentMenu(scope.row.roleId)"
                  >
                    <i />
                    <!-- radio标签label会自动填充内容,必须要一个空标签占位置 -->
                  </el-radio>
                </template>
              </el-table-column>
              <!-- <el-table-column label="序号" type="index" width="50" /> -->
              <el-table-column
                v-for="(item, index) in tableColumn"
                :key="index"
                :prop="item.prop"
                :label="item.label"
                align="center"
              >
                <template slot-scope="scope">
                  <span>{{ scope.row[scope.column.property] }}</span>
                </template>
              </el-table-column>
            </template>
          </adminTable>
        </el-main>
        <!-- 菜单目录 -->
        <el-aside width="400px">
          <el-tree
            ref="refTree"
            show-checkbox
            :data="treeData"
            :props="defaultProps"
            node-key="menuId"
            :disabled="true"
            @check="handleNodeClick"
            @check-change="checkChnage"
          />
        </el-aside>
      </el-container>
    </el-container>
  </div>
</template>

<script>
// 列表禁用封装函数
const R = (f, s) => s.map(i => {
  f(i)
  i.children && i.children !== undefined ? R(f, i.children) : 0
  return i
})
// 组件引入
import adminTable from '@/components/admin/admin-table'
import search from '@/components/admin/search.vue'
// 接口
import { menuTree, permissionRole, roleMenu, setRoleMenu } from '@/api/system'
// 页面配置
import { roleClumen1, roleJSearchs } from './count.js'
export default {
  components: {
    adminTable,
    search
  },
  data() {
    return {
      tableColumn: roleClumen1,
      searchs: roleJSearchs,
      tableData: [],
      apiFun: permissionRole,
      treeData: [],
      checkTree: [],
      defaultProps: {
        children: 'children',
        label: 'displayTitle'
      },
      selectionList: [],
      selectionId: ''
    }
  },
  computed: {
    size() {
      return this.$store.getters.size
    }
  },
  watch: {
    selectionList: {
      handler(val) {
        if (val.length >= 2) {
        // 当前选中数组大于二循环排除选中id
          const list = []
          val.filter((item, index) => {
            if (item.roleId !== this.selectionId) {
              this.selectionId = item.roleId
              list.push(item)
            }
          })
          this.selectionList = list
        } else if (val.length === 1) {
          // 只选中一个请求接口
          this.selectionId = val[0].roleId
          this.currentMenu()
        } else {
          // 其他情况清空选中ID，清空目录树菜单
          this.selectionId = ''
          this.$refs.refTree.setCheckedKeys([])
        }
      }
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    // 初始化请求接口
    async init() {
      // 菜单目录树请求
      await menuTree().then((res) => {
        this.treeData = res.data
      })
    },
    // 点击单选项选中
    getThisRow(e) {
      this.selectionList = []
      this.selectionId = e
    },
    checkChnage(data, checked, checkedNodes) {
      if (this.selectionId === '1') { // 超级--全部禁用    // 用了一个_disabled作为中间属性
        R(i => {
          if (i._disabled === undefined) {
            i._disabled = i.disabled === undefined ? false : i.disabled
          }
          i.disabled = true
        }, this.treeData)
      } else { // 自定义---取消禁用   // 用了一个_disabled作为中间属性
        R(i => {
          if (i._disabled !== undefined) {
            i.disabled = i._disabled
            delete i._disabled
          }
        }, this.treeData)
      }
    },
    // 根据选中的角色查询菜单
    currentMenu() {
      roleMenu({ roleId: this.selectionId }).then((res) => {
        // 根据 menuId设置check是否选中 node-key="menuId"
        // console.log(res.data)
        this.$refs.refTree.setCheckedKeys(res.data)
        // 存储当前角色查询选中的菜单目录 menuId
        this.checkTree = this.$refs.refTree.getCheckedKeys()
        this.checkChnage()
      })
    },
    // 菜单树选中
    handleNodeClick(data) {
      // 获取菜单改变之后的选中目录 menuId
      const checkMenu = this.$refs.refTree.getCheckedKeys()
      const menu = this.menuFilter(checkMenu, this.checkTree)
      if (this.selectionId === '1') {
        this.$message({ message: '超级管理员不可操作', type: 'warning' })
        return
      }
      if (this.selectionId) {
        // 请求接口修改菜单权限
        setRoleMenu(menu).then((res) => {
          if (res.data) {
            this.$message({ message: '操作成功', type: 'success' })
          } else {
            this.$message({ message: '操作失败', type: 'error' })
          }
        })
      } else {
        this.$message({ message: '请选择角色', type: 'warning' })
      }
    },
    // 筛选到底是取消选中还是选中对比
    menuFilter(newMenu, oldMenu) {
      let minM = oldMenu
      let maxM = newMenu
      let check = true
      // 最新选中的小于旧选中更改循环方向
      if (newMenu.length < oldMenu.length) {
        minM = newMenu
        maxM = oldMenu
        check = false
      }
      const list = []
      // 对比选中的菜单目录
      maxM.filter((items) => {
        if (!minM.includes(items)) {
          list.push(items)
        }
      })
      this.checkTree = newMenu
      return {
        checked: check,
        menuId: list,
        roleId: this.selectionId
      }
    },
    // 查询
    onSubmit(param) {
      this.$refs.refTable.getList(param)
    },
    onReset() {
      this.$refs.refTable.getList()
    }
  }
}
</script>

<style lang="scss" scoped>
.title {
  height: 30px;
  font-size: 14px;
}
.el-header {
  padding: 0;
}
.el-main {
  padding: 0;
}
.el-main ~ .el-aside {
  margin-left: 15px;
  background-color: #fff;
  border-radius: 4px;
}
.el-tree {
  background: none;
}
</style>
